/**
 * role控制器
 *
 * @author sxf
 * @email sxf02615@163.com
 * @date 2025/1/15
 */
package com.sxf.crm.controller;


import com.sxf.crm.core.entity.Role;
import com.sxf.crm.dto.RoleDTO;
import com.sxf.crm.core.entity.Permission;
import com.sxf.crm.core.service.RoleService;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import lombok.RequiredArgsConstructor;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/roles")
@RequiredArgsConstructor
public class RoleController {

    private final RoleService roleService;
    
    @PreAuthorize("hasAuthority('role:view')")
    @GetMapping
    public ResponseEntity<List<RoleDTO>> getAllRoles(@RequestParam(required = false) String name) {
        List<Role> roles = roleService.getAllRoles(name);
        List<RoleDTO> dtos = roles.stream()
                .map(RoleDTO::fromEntity)
                .collect(Collectors.toList());
        return ResponseEntity.ok(dtos);
    }

    @PreAuthorize("hasAuthority('role:view')")
    @GetMapping("/{id}")
    public ResponseEntity<RoleDTO> getRole(@PathVariable Long id) {
        return roleService.getRole(id)
                .map(role -> ResponseEntity.ok(RoleDTO.fromEntity(role)))
                .orElse(ResponseEntity.notFound().build());
    }

    @PreAuthorize("hasAuthority('role:add')")
    @PostMapping
    public ResponseEntity<RoleDTO> createRole(@RequestBody Role role, Authentication authentication) {
        Role savedRole = roleService.createRole(role);
        return ResponseEntity.ok(RoleDTO.fromEntity(savedRole));
    }

    @PreAuthorize("hasAuthority('role:edit')")
    @PutMapping("/{id}")
    public ResponseEntity<RoleDTO> updateRole(@PathVariable Long id, @RequestBody Role role, Authentication authentication) {
        role.setId(id);
        Role savedRole = roleService.updateRole(role);
        return ResponseEntity.ok(RoleDTO.fromEntity(savedRole));
    }

    @PreAuthorize("hasAuthority('role:delete')")
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteRole(@PathVariable Long id, Authentication authentication) {
        roleService.getRole(id)
                .orElseThrow(() -> new RuntimeException("Role not found"));
        roleService.deleteRole(id);

        return ResponseEntity.ok().build();
    }

    @PreAuthorize("hasAuthority('role:view')")
    @GetMapping("/{id}/permissions")
    public ResponseEntity<Set<Permission>> getRolePermissions(@PathVariable Long id) {
        return roleService.getRole(id)
                .map(role -> ResponseEntity.ok(role.getPermissions()))
                .orElse(ResponseEntity.notFound().build());
    }

    @PreAuthorize("hasAuthority('role:edit')")
    @PutMapping("/{id}/permissions")
    public ResponseEntity<Role> updateRolePermissions(
            @PathVariable Long id,
            @RequestBody List<Long> permissionIds,
            Authentication authentication,
            HttpServletRequest request) {
        Role role = roleService.getRole(id)
                .orElseThrow(() -> new RuntimeException("Role not found"));
        Role updatedRole = roleService.updateRolePermissions(id, permissionIds);

        return ResponseEntity.ok(updatedRole);
    }

}
